home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c-part1 / 3506 < prev    next >
Encoding:
Internet Message Format  |  1996-08-05  |  5.1 KB

  1. Path: news.delphi.com!usenet
  2. From: Derek Harmon <stonelight@delphi.com>
  3. Newsgroups: comp.lang.c
  4. Subject: Re: New C Programmer Has A Problem
  5. Date: Mon, 29 Jan 96 11:43:57 -0500
  6. Organization: Delphi (info@delphi.com email, 800-695-4005 voice)
  7. Message-ID: <ZtBK4dl.stonelight@delphi.com>
  8. References: <4ehpa3$6kl@nntp.novia.net>
  9. NNTP-Posting-Host: bos1g.delphi.com
  10. X-To: Tony Syslo <tsyslo@oasis.novia.net>
  11.  
  12.  
  13. Quoting a message by tsyslo@oasis.novia.net dated <29-Jan-1996>:
  14. >  I have a question on C... why isn't this program working?!
  15.  
  16.     This isn't a very good way to start off, Tony.  It would help to know
  17. where you suspect the problem might be.  I'll assume it compiles okay,
  18. generating a "Couldn't open the file" message isn't the problem, nor are
  19. you having any problems reading STDIN with scanf() (a dangerous practice
  20. IMO).
  21.  
  22.     Let's have a look at your program:
  23.  
  24. >  void main();
  25. >
  26. >     char *name;
  27. >     int age;
  28.  
  29.     Name is a pointer.  It points to a string of characters, terminated
  30. by a Null ('/0').  It's size is implementation-dependent, but is generally
  31. 2-bytes or 4-bytes.  In most cases, C allows you the freedom to treat a
  32. (char *) as an array of char, but I suspect you get caught in a trap due
  33. to this later.  I also don't see name initially allocated any memory,
  34. either directly or indirectly.   So for now I suggest:
  35.  
  36. :   char name[20];
  37. :   int age;
  38.  
  39. >     long bytes_written;
  40. >     long bytes_read;
  41.  
  42.     I didn't see anyplace in your code where these are initialized to
  43. (presumably) zero.
  44.  
  45. >    printf("\nEnter your age: ");  scanf("%d",age);
  46.  
  47.     This might not work, because age is an integer, not a pointer to an
  48. integer.  It was okay for name, because name was a pointer to a char..
  49. but not good for age.  I would reccommend:
  50.  
  51. :    printf("\nEnter your age: ");  scanf("%d", &age);
  52.  
  53.     The &-operator tells C to use the address-of age, which is what scanf()
  54. wants.  I suspect your program probably blew-up here.
  55.  
  56. >     /* We have now opened a file, and are ready to start writing: */
  57. >     bytes_written=Write(file_handle,name,sizeof(name));
  58. >     bytes_written=bytes_written+Write(file_handle,age,sizeof(age));
  59. >
  60.  
  61.     Here there are 2 problems.  write() is similar to scanf() in that it
  62. requires a file handle, a pointer addressing an element of data, and how many
  63. bytes it should write beginning at that location.  So, while the first line
  64. works in this regard for name (since it is a pointer), the second will write
  65. not the value of age (if age were 8, say) but whatever it finds at address
  66. 0000:0008.  Which, on a Unix would probably get you a Segmentation fault,
  67. and elsewhere would get you garbage, but would not get you 8.
  68.  
  69.     Unfortunately, the first line isn't totally fault-free either.  If name
  70. were an array of char, say, char name[20], then sizeof(name) would be 20.
  71. That would be alright.  However, as name is a POINTER to a char, and a
  72. pointer is 2 or 4 bytes long, sizeof(name) is 2 or 4.  printf("%s",name)
  73. might be "Humperdink", strlen(name) would be 10, but sizeof(name) will
  74. always be 2 or 4.  There are 2 ways around this:  (a) use strlen(name)
  75. instead of sizeof(name), but I would rule this out as it turns your fixed-
  76. length field file into a more complicated variable-length field file.
  77. (b) make name an array of char.
  78.  
  79. :     bytes_written = Write(file_handle,name,sizeof(name));
  80. :     bytes_written += Write(file_handle,&age,sizeof(age));
  81.  
  82. >     if(bytes_written!=sizeof(name)+sizeof(age))
  83. :      /* could not save list */
  84. :   else
  85. :      /* save is GOOD, save is GOOD! */
  86.  
  87.     Same thing, but will work the first time through when name is an array.
  88.  
  89. >     printf("Memory cleared!\n");
  90. >      name="";
  91. >      age=0;
  92.  
  93.     If, though, you are clearing memory (perhaps to include this in a loop
  94. sometime in the future), you should include bytes_written (and read) = 0.
  95. Otherwise, for tests after the first, bytes_written will have accumulated
  96. a value greater than sizeof(name) + sizeof(age) above.
  97.  
  98.     Also, name="" is a dangerous (BASIC-like) way to nullify a string in C,
  99. although it may work in this instance (equiv to saying name[0] = '\0').
  100.  
  101. >     bytes_read=Read(file_handle,name,sizeof(name));
  102. >     bytes_read=bytes_read+Read(file_handle,age,sizeof(age));
  103.  
  104. :     bytes_read = Read(file_handle,name,sizeof(name));
  105. :     bytes_read += Read(file_handle,&age,sizeof(age));
  106.  
  107.     Again, same thing with read() requiring a buffer to read the data into,
  108. age is a integer, &age is the address of an integer, so use &age instead.
  109.  
  110. >  Program END:
  111.  
  112.     In summary,
  113.  
  114.     1) Many C functions require a "buffer" which they write/read data to/from.
  115.     If this is the case, you must either pass them a variable that is a pointer
  116.     (ie, a char * or array) in which case you just use the variable name.  Or,
  117.     you can pass them a variable that is not a pointer (an int, char, struct)
  118.     but you must prefix it with the address-of operator, &.  This is often
  119.     a case with I/O functions.  Check the prototypes in any headers, ie:
  120.  
  121.     int write(int handle, void *buf, unsigned len);
  122.                                         ^
  123.                                          \___ asterisk indicates expecting a pointer.
  124.  
  125.     2) When using strings, be careful.  Strings in C are very TWICKY!
  126.  
  127. >  Any help if MUCH appreciated...
  128.  
  129.     Hope this helps.
  130.  
  131.                                                                     - Stone
  132. --
  133. ... The generation of random numbers is too important to be left to chance.
  134.  
  135.